package com.ofps.forms.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.impl.JWTParser;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.jar.JarException;

/**
 * @author pyn
 * @date 2022/5/9 - 7:33
 * <p>
 * ***JWT JSON WEB TOKEN
 * TOKEN     vs    SESSION/COOKIE
 * 服务器生成      服务器生成/持有SESSION
 * 客户端持有      客户端持有COOKIE
 * <p>
 * Base加密  可以逆向获取内容
 * Header           +   payload +      signature
 * (Type+Algorithm)   (username id)   (salt+Header+payload  HMAC256)
 * <p>
 * /*****************************
 * 令牌生成
 * base64urlencode（Header）
 * +"."+
 * base64urlencode（Playload）
 * +"."+
 * signature（
 * base64urlencode（Header）
 * +"."+
 * base64urlencode（Playload）
 * ,secret-key
 * ）
 */

public class JwtUtil {
    //自定义盐值 加密时使用 不可以外传
    private final static String SALT = "qwerty4192poiuy!@#$$%";
    //过期时间
    private final static Long EXPIRE_TIME = 1000 * 60 * 60 * 12L;//2小时

    //获取一个token 负载为用户名和用户id
    public static String getJWToken(HashMap<String, String> payLoadMap) {
        return JWT.create()
                .withHeader(new HashMap<>())//Header 默认 Type:JWT   Alg:HS256
                .withClaim("username", payLoadMap.get("username"))//有效载荷
                .withClaim("id", (payLoadMap.get("id")))//有效在和
                .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRE_TIME))//过期时间 当前时间+
                .sign(Algorithm.HMAC256(SALT));//加盐+加密算法
    }

    /**
     * 校验token是否正确
     *
     * @param token 密钥
     * @return 如果token有效返回true，否则返回false
     */
    public static boolean checkToken(String token) {
        try {
            // 从http请求头中获取token字符串
            if (StringUtils.isEmpty(token)) return false;
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SALT)).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    //解析JWToken  获取用户名+id
    public static HashMap<String, Object> parserJWToken(String token) {
        HashMap<String, Object> map = new HashMap<>();
        // 创建解析对象，使用的算法和secret要与创建token时保持一致
        try {
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SALT)).build();
            // 解析指定的token
            DecodedJWT decodedJWT = jwtVerifier.verify(token);
            // 获取解析后的token中的payload信息

            Claim id = decodedJWT.getClaim("id");
            Claim username = decodedJWT.getClaim("username");
            map.put("id", id.asString());
            map.put("username", username.asString());
            map.put("expiration", decodedJWT.getExpiresAt());
            return map;
        } catch (JWTDecodeException e) {
            return null;
        }

    }

    public static boolean isTokenExpired(Date expiration) {
        return expiration.before(new Date());
    }

}
